package com.elight.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.elight.entity.Keys;
import com.elight.entity.Level;
import com.elight.entity.Operator;
import com.elight.filter.LoginChecked;
import com.elight.sys.entity.SysUser;
import com.elight.sys.entity.SysUserLogOn;
import com.elight.sys.service.AccountService;
import com.elight.sys.service.LogService;
import com.elight.utils.Encrypt;
import com.elight.utils.GsonUtils;
import com.elight.utils.MD5Util;
import com.elight.utils.NetUtils;
import com.elight.utils.OperatorProvider;
import com.elight.utils.PropertyPlaceholder;
import com.elight.utils.StringUtils;

@RestController
@RequestMapping(value = "/Account")
public class AccountController extends BaseController {
	@Autowired(required = true)
	private AccountService accountService;
	@Autowired(required = true)
	private LogService logService;

	/**
	 * 用户登录页面
	 * @return
	 */
	@RequestMapping(value = "/Login", method = { RequestMethod.GET })
	public ModelAndView login() {
		ModelAndView view = new ModelAndView();
		view.addObject("SoftwareName", PropertyPlaceholder.getProperty("softwareName"));
		view.setViewName("/System/Account/Login");
		return view;
	}

	/**
	 * 获取验证码图片
	 * @param request
	 * @param response
	 * @param session
	 * @throws IOException
	 */
	@RequestMapping(value = "/VerifyCode", method = { RequestMethod.GET })
	public void verifyCode(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		int width = 63;
		int height = 37;
		Random random = new Random();
		// 设置response头信息
		// 禁止缓存
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);

		// 生成缓冲区image类
		BufferedImage image = new BufferedImage(width, height, 1);
		// 产生image类的Graphics用于绘制操作
		Graphics g = image.getGraphics();
		// Graphics类的样式
		g.setColor(getRandColor(200, 250));
		g.setFont(new Font("Times New Roman", 0, 28));
		g.fillRect(0, 0, width, height);
		// 绘制干扰线
		for (int i = 0; i < 40; i++) {
			g.setColor(getRandColor(130, 200));
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int x1 = random.nextInt(12);
			int y1 = random.nextInt(12);
			g.drawLine(x, y, x + x1, y + y1);
		}

		// 绘制字符
		String strCode = "";
		for (int i = 0; i < 4; i++) {
			String rand = String.valueOf(random.nextInt(10));
			strCode = strCode + rand;
			g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
			g.drawString(rand, 13 * i + 6, 28);
		}
		// 将字符保存到session中用于前端的验证
		session.setAttribute(Keys.SESSION_KEY_VCODE, strCode.toLowerCase());
		g.dispose();
		ImageIO.write(image, "JPEG", response.getOutputStream());
		response.getOutputStream().flush();
	}

	public Color getRandColor(int fc, int bc) {
		Random random = new Random();
		if (fc > 255)
			fc = 255;
		if (bc > 255)
			bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

	/**
	 * 登录功能
	 * @param session
	 * @param userName
	 * @param password
	 * @param verifyCode
	 * @return
	 */
	@RequestMapping(value = "/Login", method = { RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String login(HttpServletRequest request, String userName, String password, String verifyCode) {
		if (StringUtils.isNullOrEmpty(userName) || StringUtils.isNullOrEmpty(password)|| StringUtils.isNullOrEmpty(verifyCode)) {
			return error("请求失败，缺少必要参数。");
		}
		if (!verifyCode.toLowerCase().equals(request.getSession().getAttribute(Keys.SESSION_KEY_VCODE))) {
			return warning("验证码错误，请重新输入。");
		}
		SysUser userEntity = accountService.getByUserName(userName);
		if (userEntity == null) {
			return warning("该账户不存在，请重新输入。");
		}
		if (!userEntity.getIsEnabled().equals("1")) {
			return warning("该账户已被禁用，请联系管理员。");
		}
		SysUserLogOn userLogOnEntity = accountService.getByAccount(userEntity.getId());
		String inputPassword = MD5Util.MD5(Encrypt.DESEncrypt(password, userLogOnEntity.getSecretKey())).toLowerCase();
		if (!inputPassword.equals(userLogOnEntity.getPassword())) {
			logService.write(Level.Info, "系统登录", "密码错误", userEntity.getAccount(), userEntity.getRealName(),NetUtils.getIP(request),NetUtils.getBrowser(request));
			return warning("密码错误，请重新输入。");
		} else {
			Operator operatorModel = new Operator();
			operatorModel.setUserId(userEntity.getId());
			operatorModel.setAccount(userEntity.getAccount());
			operatorModel.setRealName(userEntity.getRealName());
			operatorModel.setAvatar(userEntity.getAvatar());
			operatorModel.setCompanyId(userEntity.getCompanyId());
			operatorModel.setDepartmentId(userEntity.getDepartmentId());
			operatorModel.setLoginTime(new Date());
			operatorModel.setToken(Encrypt.DESEncrypt(UUID.randomUUID().toString().replaceAll("-", "")));
			request.getSession().setAttribute("LoginUser", Encrypt.DESEncrypt(GsonUtils.objToJSON(operatorModel)));
			accountService.updateLogin(userLogOnEntity);
			logService.write(Level.Info, "系统登录", "登录成功", userEntity.getAccount(), userEntity.getRealName(),NetUtils.getIP(request),NetUtils.getBrowser(request));
			return success();
		}
	}

	
	/**
	 * 退出登录
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/Exit", method = { RequestMethod.GET })
	public ModelAndView exit(HttpSession session) {
		if (OperatorProvider.getCurrent(session) != null) {
			OperatorProvider.remove(session);
		}
		ModelAndView view = new ModelAndView();
		view.addObject("SoftwareName", PropertyPlaceholder.getProperty("softwareName"));
		view.setViewName("/System/Account/Login");
		return view;
	}

	/**
	 * 锁定登录用户
	 * @param session
	 * @return
	 */
	@LoginChecked()
	@RequestMapping(value = "/Lock", method = { RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String lock(HttpSession session) {
		if (OperatorProvider.getCurrent(session) != null) {
			OperatorProvider.remove(session);
		}
		return success();
	}

	/**
	 * 解锁用户登录
	 * @param session
	 * @param username
	 * @param password
	 * @return
	 */
	@RequestMapping(value = "/Unlock", method = { RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String unlock(HttpSession session, String username, String password) {
		SysUser userEntity = accountService.getByUserName(username);
		SysUserLogOn userLogOnEntity = accountService.getByAccount(userEntity.getId());
		String inputPassword = MD5Util.MD5(Encrypt.DESEncrypt(password, userLogOnEntity.getSecretKey())).toLowerCase();
		if (!inputPassword.equals(userLogOnEntity.getPassword())) {
			return warning("密码错误，请重新输入。");
		} else {
			// 重新保存用户信息。
			Operator operatorModel = new Operator();
			operatorModel.setUserId(userEntity.getId());
			operatorModel.setAccount(userEntity.getAccount());
			operatorModel.setRealName(userEntity.getRealName());
			operatorModel.setAvatar(userEntity.getAvatar());
			operatorModel.setCompanyId(userEntity.getCompanyId());
			operatorModel.setDepartmentId(userEntity.getDepartmentId());
			operatorModel.setLoginTime(new Date());
			operatorModel.setToken(Encrypt.DESEncrypt(UUID.randomUUID().toString().replaceAll("-", "")));
			session.setAttribute("LoginUser", Encrypt.DESEncrypt(GsonUtils.objToJSON(operatorModel)));
		}
		return success();
	}

	/**
	 * 用户账户管理视图
	 * @return
	 */
	@LoginChecked()
	@RequestMapping(value = "/InfoCard", method = { RequestMethod.GET })
	public ModelAndView infoCard() {
		return new ModelAndView("/System/Account/InfoCard");
	}

	/**
	 * 用户信息修改
	 * @param model
	 * @return
	 */
	@LoginChecked()
	@RequestMapping(value = "/InfoCard", method = { RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String infoCard(SysUser model) {
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			Date defaultDt = format.parse(model.getStrBirthDay());
			model.setBirthday(defaultDt);
			int row = accountService.updateBasicInfo(model);
			return row > 0 ? success() : error();
		} catch (Exception e) {
			return error();
		}
	}

	/**
	 * 获得用户信息
	 * @param session
	 * @return
	 */
	@LoginChecked()
	@RequestMapping(value = "/GetInfoCardForm", method = {RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String getInfoCardForm(HttpSession session) {
		String userId = OperatorProvider.getCurrent(session).getUserId();
		SysUser userEntity = accountService.getUser(userId);
		return GsonUtils.objToJSON(userEntity);
	}

	/**
	 * 上传头像。
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/UploadAvatar", method = {RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String uploadAvatar(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request) {
		if(file == null)
			return error();
		if(file.isEmpty())
			return error();
		String ext = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf("."));// 取文件格式后缀名
		String fileName = UUID.randomUUID().toString().replace("-", "") + ext;
		String virtualPath = "/Uploads/Avatar/" + fileName;
		String rootPath = request.getSession().getServletContext().getRealPath("/").replace("\\", "/");
		if (!rootPath.endsWith("/"))
			rootPath += "/";
		rootPath+="WEB-INF/";
		String uploadDir = rootPath + "Uploads/";
		File uploadDirFile = new File(uploadDir);
		if (!uploadDirFile.exists()) {
			uploadDirFile.mkdirs();
		}
		String avatarPath = uploadDir + "Avatar/";
		File avatarPathFile = new File(avatarPath);
		if (!avatarPathFile.exists()) {
			avatarPathFile.mkdirs();
		}
		String path = avatarPath + fileName;// 存放位置
		File destFile = new File(path);
		if (destFile.exists()) {
			destFile.delete();
		}
		try {
			file.transferTo(destFile);
			return success("上传成功。", virtualPath);
		} catch (IOException e) {
			return error();
		}
	}

	/**
	 * 上传图片
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/UploadImage", method = {RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String uploadImage(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request)
	{
		if(file == null)
			return error();
		if(file.isEmpty())
			return error();
		String ext = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf("."));// 取文件格式后缀名
		String fileName = UUID.randomUUID().toString().replace("-", "") + ext;
		String virtualPath = "/Uploads/Avatar/" + fileName;
		String rootPath = request.getSession().getServletContext().getRealPath("/").replace("\\", "/");
		if (!rootPath.endsWith("/"))
			rootPath += "/";
		rootPath+="WEB-INF/";
		String uploadDir = rootPath + "Uploads/";
		File uploadDirFile = new File(uploadDir);
		if (!uploadDirFile.exists()) {
			uploadDirFile.mkdirs();
		}
		String avatarPath = uploadDir + "Avatar/";
		File avatarPathFile = new File(avatarPath);
		if (!avatarPathFile.exists()) {
			avatarPathFile.mkdirs();
		}
		String path = avatarPath + fileName;// 存放位置
		File destFile = new File(path);
		if (destFile.exists()) {
			destFile.delete();
		}
		try {
			file.transferTo(destFile);
			return success("上传成功。", virtualPath);
		} catch (IOException e) {
			return error();
		}
	}

	/**
	 * 修改密码画面
	 * @return
	 */
	@LoginChecked()
	@RequestMapping(value = "/ModifyPwd", method = { RequestMethod.GET })
	public ModelAndView modifyPwd() {
		return new ModelAndView("/System/Account/ModifyPwd");
	}

	/**
	 * 修改密码
	 * @param session
	 * @param oldPassword
	 * @param newPassword
	 * @param confirmPassword
	 * @return
	 */
	@LoginChecked()
	@RequestMapping(value = "/ModifyPwd", method = { RequestMethod.POST }, produces = "application/json; charset=utf-8")
	public String modifyPwd(HttpSession session, String oldPassword, String newPassword, String confirmPassword) {
		if (StringUtils.isNullOrEmpty(oldPassword) || StringUtils.isNullOrEmpty(newPassword) || StringUtils.isNullOrEmpty(confirmPassword)) {
			return error("请求失败，缺少必要参数。");
		}
		if (!newPassword.equals(confirmPassword)) {
			return warning("两次密码输入不一致，请重新确认。");
		}
		String userId = OperatorProvider.getCurrent(session).getUserId();
		SysUserLogOn userLoginEntity = accountService.getByAccount(userId);
		if (!MD5Util.MD5(Encrypt.DESEncrypt(oldPassword, userLoginEntity.getSecretKey())).toLowerCase().equals(userLoginEntity.getPassword())) {
			return warning("旧密码验证失败。");
		}
		userLoginEntity.setPassword(MD5Util.MD5(Encrypt.DESEncrypt(newPassword, userLoginEntity.getSecretKey())).toLowerCase());
		int flag = accountService.modifyPwd(userLoginEntity);
		return flag > 0 ? success() : error();
	}
}
